package com.evan.common.controller;

import com.evan.common.bit.ReturnResEnum;
import com.evan.common.exception.ZkException;
import com.evan.common.pojo.NodeData;
import com.evan.common.pojo.Result;
import com.evan.common.pojo.ZkServerInfo;
import com.evan.common.service.ZkServerService;
import com.evan.common.service.impl.ZkServerServiceImpl;
import com.evan.common.utils.ZookeeperClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.apache.zookeeper.CreateMode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@RestController
@Api("Zookeeper 操作")
@RequestMapping("/zk")
public class ZkServerController {

    @Autowired
    private ZkServerService zs = new ZkServerServiceImpl();

    @GetMapping("/cluster")
    @ApiOperation("获取zookeeper所有节点")
    public List<ZkServerInfo> getZk(){
        return zs.getAllZkNode();
    }

    @PostMapping("/add")
    @ApiOperation("添加zookeeper节点")
    public ZkServerInfo addZkNode(
            @RequestParam(value = "clusterId",defaultValue = "1",required = false) int cluster_id
            , ZkServerInfo zk) throws Exception {
        return zs.addZkNode(zk);
    }

    @PostMapping("/status")
    @ApiOperation("获取zookeeper节点状态")
    public List<Map<String,String>> getZkNodeStatus() throws Exception {
        return zs.getZkStatus();
    }

    @PostMapping("/hostStat")
    @ApiOperation("获取单个zk节点状态")
    public Map<String,List<String>> getZkStat(String host,int port,String command) throws IOException {
        return zs.getZkStatus(host,port,command);
    }

    @PostMapping("/readZNodeData")
    @ApiOperation("获取节点数据")
    public String getZNodeData(
            @RequestParam(value = "path") String path
            ,@RequestParam(value = "clusterId",required = false,defaultValue = "1") int clusterId) throws Exception {
        String zkHostInfos = zs.getZkHostInfos(clusterId);
        ZookeeperClient client = new ZookeeperClient(zkHostInfos, 5000);
        if (!client.exists(path)){
            return path + " is not exists.";
        }else{
            NodeData data = client.getData(path);
            return data.getData();
        }

    }

    @PostMapping("/createZNode")
    @ApiOperation("创建节点给定初始化数据")
    public String createZNode(@RequestParam(value = "clusterId",defaultValue = "1") Integer cid,
                              @RequestParam(value = "nodePath") String path,
                              @RequestParam(value = "initData",defaultValue = "",required = false) String initData,
                              @RequestParam(value = "pathMode",defaultValue = "",required = false) CreateMode pathMode) throws Exception {
        assert path != null || path != "" : "path not can empty.";
        if(pathMode == null){
            pathMode = CreateMode.EPHEMERAL;
        }
        String zkHostInfos = zs.getZkHostInfos(cid);
        String resNodePath = zs.createZNode(zkHostInfos,path,initData,pathMode);
        return resNodePath;
    }

    @PostMapping("/delZNode")
    @ApiOperation("删除节点")
    public Result delZNode(@RequestParam(value = "clusterId",defaultValue = "1") Integer cid,
                         @RequestParam(value = "nodePath") String path) throws Exception {
        assert path != null || path != "" : "path not can empty.";
        zs.delZNode(zs.getZkHostInfos(cid),path);
        return new Result(ReturnResEnum.SUCCESS);
    }

    @GetMapping("/getZnodeChildren")
    public Result getZNodeChildren(@RequestParam(value = "path",required = true) String path,
                                   @RequestParam(value = "cid",defaultValue = "1") Integer cid)
            throws Exception {

        assert path != null || path != "" : "path not can empty.";
        List<String> znodeChildren = zs.getZnodeChildren(path, getZkHostsByClusterId(cid));
        Result result = new Result(ReturnResEnum.SUCCESS, znodeChildren);
        return result;
    }

    public String getZkHostsByClusterId(Integer cid) throws ZkException {
        return zs.getZkHostInfos(cid);
    }

}
